#include <fstream>
#include <functional>
#include <locale>
#include <algorithm>
#include <iostream>
#include <string>
#include "Normalizador.h"

using namespace std;

int Normalizador::normalizar(string entrada, string salida){
	// Abre el archivo como wide char, el archivo debe ser UTF-8
	wifstream fin(entrada.c_str());

	// Se fuerza que el locale con el que trabajamos sea UTF-8
	// (este deberia ser el valor por defecto, pero varia por PC)
	locale loc("es_AR.UTF8");
	fin.imbue(loc);

	// Donde guardamos el resultado
	ofstream fout(salida.c_str());

	while ( !fin.eof() ){

		// Leemos una linea entera del archivo
		wstring linea;
		getline(fin, linea);

		// To lower case, robado de:
		// http://stackoverflow.com/questions/313970/stl-string-to-lower-case
		transform(linea.begin(), linea.end(), linea.begin(),
			bind2nd(ptr_fun(&tolower<wchar_t>),
			locale("es_AR.UTF8")));


		// Procesamos los caracteres uno a uno
		string s = "";
		for (unsigned i=0; i < linea.length(); ++i){

			// Se filtra el caracter y se lo agrega al final del string
			char c = filtrarChar(linea[i]);
			s.push_back(c);
		}

		// Se guarda la linea en el archivo de salida
		fout << s << endl;
	}

	fin.close();
	fout.close();

	return 0;
}//normalizar


char Normalizador::transformarChar(wchar_t c){
	int cint = (int) c;
	switch (cint){
			case (int) L'á':
			case (int) L'ä':
				return 'a';

			case (int) L'é':
			case (int) L'ë':
				return 'e';

			case (int) L'í':
			case (int) L'ï':
			case (int) L'î':
				return 'i';

			case (int) L'ó':
			case (int) L'ö':
				return 'o';

			case (int) L'ú':
			case (int) L'ü':
				return 'u';

			case (int) L'ñ':
				return 'n';

			// Tambien hay palabras que tienen puntos (ejem: T.N.T.)
			case (int) L'.':
				return '.';

			default:
				// Un caracter que no se que es
				return '-';
		}
}//transformar char



char Normalizador::filtrarChar(wchar_t c){

	// Convierte el caracter en numero
	int ci = (int) c;

	// Los valores de los caracters permitidos
	int a = (int) 'a';
	int z = (int) 'z';
	int A = (int) 'A';
	int Z = (int) 'Z';

	// Compara que el caracter este dentro de los valores de las letras "normales"
	if ( (ci >= a && ci <= z) || (ci >= A && ci <=Z) ){

		// Es una letra normal, lo casteo y lo devuelvo
		return c;

	} else {
		// Es un caracter "raro", con asento o algo parecido,
		// hay que aplicarle una transformacion
		return transformarChar(c);
	}
}//filtrarChar









